package rarutil

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/mholt/archiver"
	"github.com/nwaples/rardecode"
)

/**
 * 读取指定(序号)文件
 * source 源文件
 * Index 序号
 * (bool, string, interface{}) (content []byte, fileName string)
 */
func Read(source string, Index int) (bool, string, interface{}) {
	source = strings.TrimSpace(source)

	if _, err := os.Stat(source); err != nil {
		if os.IsNotExist(err) {
			return false, "源文件不存在", 1001
		}

		return false, "访问源文件异常:" + err.Error(), 1002
	}

	r := archiver.NewRar()

	var result []byte
	fileName := ""
	index := -1
	err := r.Walk(source, func(f archiver.File) error {
		index++

		if index != Index {
			return nil
		}

		rh, ok := f.Header.(*rardecode.FileHeader)
		if !ok {
			return fmt.Errorf("读取文件头失败")
		}
		// fmt.Println("FileName:", rh.Name)

		content, err := io.ReadAll(f)
		if err != nil {
			return err
		}

		result = content
		fileName = rh.Name

		return fmt.Errorf("找到")
	})

	if err != nil {
		return false, "读取文件失败:" + err.Error(), 1003
	}

	if fileName == "" {
		return false, "未找到文件", 1004
	}

	return true, fileName, result
}

/**
 * 读取指定(序号)文件
 * source 源文件
 * Index 序号
 * (bool, string, interface{}) (content []byte, fileName string)
 */
func ReadByIndex(source string, Index int) (bool, string, interface{}) {
	return Read(source, Index)
}

/**
 * 读取指定(名称)文件
 * source 源文件
 * Index 序号
 * (bool, string, interface{}) (content []byte, fileName string)
 */
func ReadByName(source, Name string) (bool, string, interface{}) {
	source = strings.TrimSpace(source)

	if _, err := os.Stat(source); err != nil {
		if os.IsNotExist(err) {
			return false, "源文件不存在", 1001
		}

		return false, "访问源文件异常:" + err.Error(), 1002
	}

	Name = strings.TrimSpace(Name)

	r := archiver.NewRar()

	var result []byte
	fileName := ""
	err := r.Walk(source, func(f archiver.File) error {
		rh, ok := f.Header.(*rardecode.FileHeader)
		if !ok {
			return fmt.Errorf("读取文件头失败")
		}

		if Name != rh.Name {
			return nil
		}
		// fmt.Println("FileName:", rh.Name)

		content, err := io.ReadAll(f)
		if err != nil {
			return err
		}

		result = content
		fileName = rh.Name

		return fmt.Errorf("找到")
	})

	if err != nil {
		return false, "读取文件失败:" + err.Error(), 1003
	}

	if fileName == "" {
		return false, "未找到文件:" + Name, 1004
	}

	return true, fileName, result
}

/**
 * 解压文件
 * source 源文件
 * targe 目标路径
 * (bool, string, interface{}) (int, msg)
 */
func Unpack(source, targe string) (bool, string, interface{}) {
	source = strings.TrimSpace(source)

	if _, err := os.Stat(source); err != nil {
		if os.IsNotExist(err) {
			return false, "源文件不存在", 1001
		}

		return false, "访问源文件异常:" + err.Error(), 1002
	}

	targe = strings.TrimSpace(targe)

	r := archiver.NewRar()

	err := r.Unarchive(source, targe)
	if err != nil {
		return false, "解压文件异常:" + err.Error(), 1003
	}

	return true, "解压完毕", 1999
}
